import * as React from 'react';
import { View, Text, Animated, StyleSheet, ActivityIndicator, TouchableOpacity } from 'react-native';
import { SwipeListView, RowMap } from 'react-native-swipe-list-view'



import {
    FlatListRefreshProps,
    SectionListRefreshProps,
    SwipeListViewRefreshProps,
    RefreshListProps,
    RefreshState,
    RefreshText
} from './index'




export default React.forwardRef((props: RefreshListProps, ref: React.Ref<any>) => {
    const {
        mode = 'FlatList',
        refreshState,
        onHeaderRefresh,
        onFooterRefresh,
        reload,
        ...rest
    } = props


    const seed = React.useRef(Math.random()).current


    let onRefresh = () => {
        if (refreshState == RefreshState.HeaderRefreshing) return
        if (refreshState == RefreshState.FooterRefreshing) return
        onHeaderRefresh && onHeaderRefresh(RefreshState.HeaderRefreshing)
    }

    let onEndReached = (info: unknown) => {

        if (mode == 'FlatList') {
            props = props as FlatListRefreshProps;
            if (!(props.data instanceof Array)) {
                throw new Error('[sg:FlatList] data is not Array')
            }
            if (props.data.length == 0) return
        }

        if (mode == 'SectionList') {
            props = props as SectionListRefreshProps;
            if (!(props.sections instanceof Array)) {
                throw new Error('[sg:SectionList] sections is not Array')
            }
            if (props.sections.length == 0) return
        }

        if (refreshState != RefreshState.Idle) return
        onFooterRefresh && onFooterRefresh(RefreshState.FooterRefreshing)
    }



    switch (mode) {
        case 'FlatList':
            let flatListProps: FlatListRefreshProps = props as FlatListRefreshProps
            return (
                <Animated.FlatList
                    {...rest as FlatListRefreshProps}
                    ref={ref}
                    refreshing={refreshState == RefreshState.HeaderRefreshing}
                    keyExtractor={(_, index) => { return `sg-index-FlatList-${seed}-${index}` }}
                    contentContainerStyle={flatListProps.data?.length ? {} : { height: "100%" }}
                    onRefresh={onRefresh}
                    onEndReachedThreshold={0.1}
                    onEndReached={onEndReached}
                    showsVerticalScrollIndicator={false}
                    ListHeaderComponent={(_) => (
                        <View style={{ display: 'flex', flexDirection: 'column' }}>
                            <ListHeaderComponent {...flatListProps} />
                            {flatListProps.ListHeaderComponent}
                        </View>
                    )}
                    ListFooterComponent={(_) => <ListFooterComponent {...flatListProps} />}

                />
            )

        case 'SectionList':
            let sectionListProps: SectionListRefreshProps = props as SectionListRefreshProps;
            const { ItemSeparatorComponent = (_) => (
                <View style={{ height: 1 }} />
            ) } = sectionListProps
            return (
                <Animated.SectionList
                    {...rest as SectionListRefreshProps}
                    ref={ref}
                    refreshing={refreshState == RefreshState.HeaderRefreshing}
                    onRefresh={onRefresh}
                    keyExtractor={(_, index) => { return `sg-index-SectionList-${seed}-${index}` }}
                    contentContainerStyle={sectionListProps.sections?.length > 0 ? {} : { height: "100%" }}
                    ItemSeparatorComponent={ItemSeparatorComponent}
                    onEndReachedThreshold={0.1}
                    onEndReached={onEndReached}
                    showsVerticalScrollIndicator={false}
                    // ListHeaderComponent={(_) => <ListHeaderComponent {...sectionListProps} />}
                    ListHeaderComponent={(_) => (
                        <View style={{ display: 'flex', flexDirection: 'column' }}>
                            <ListHeaderComponent {...flatListProps} />
                            {sectionListProps.ListHeaderComponent}
                        </View>
                    )}
                    ListFooterComponent={(_) => <ListFooterComponent {...sectionListProps} />}
                    renderSectionHeader={sectionListProps.renderSectionHeader}
                />
            )

        case 'SwipeList':
            let swipeListProps: SwipeListViewRefreshProps = props as SwipeListViewRefreshProps
            const { renderHiddenItem = (data, rowMap) => (
                <View style={{ backgroundColor: 'red', height: '100%', alignItems: 'flex-end', justifyContent: "center" }}>
                    <Text>Right </Text>
                </View>
            ) } = swipeListProps
            return (
                <SwipeListView
                    {...rest as SwipeListViewRefreshProps}
                    rightOpenValue={-100}
                    leftOpenValue={0}
                    ref={ref}
                    disableLeftSwipe={false}
                    disableRightSwipe={true}
                    onRefresh={onRefresh}
                    refreshing={refreshState == RefreshState.HeaderRefreshing}
                    ItemSeparatorComponent={ItemSeparatorComponent}
                    onEndReachedThreshold={0.1}
                    onEndReached={onEndReached}
                    showsVerticalScrollIndicator={false}
                    ListHeaderComponent={(_) => (
                        <View style={{ display: 'flex', flexDirection: 'column' }}>
                            <ListHeaderComponent {...flatListProps} />
                            {swipeListProps.ListHeaderComponent}
                        </View>
                    )}
                    ListFooterComponent={(args) => <ListFooterComponent {...swipeListProps} />}
                    renderHiddenItem={renderHiddenItem}
                />

            )
    }

})







const ListFooterComponent = React.memo((props: RefreshListProps) => {
    const {
        refreshState,
        reload,
    } = props

    switch (refreshState) {
        case RefreshState.Idle:
        case RefreshState.FooterRefreshing:
            return (
                <View style={{ ...styles.container, flexDirection: 'row' }}>
                    <ActivityIndicator color={'gray'} />
                    <Text style={{ ...styles.text, marginLeft: 5 }}>{RefreshText.FooterRefreshing}</Text>
                </View>
            )
        case RefreshState.NoMoreData:
            return (
                <View style={styles.container}>
                    <Text style={{ ...styles.text, color: '#999999' }}>{RefreshText.NoMoreData}</Text>
                </View>
            )
        case RefreshState.Failure:
            return (
                <View style={styles.container}>
                    <TouchableOpacity onPress={() => reload && reload()}>
                        <Text style={styles.text}>{RefreshText.Failure}</Text>
                    </TouchableOpacity>
                </View>
            )
        case RefreshState.EmptyData:
            if (props.renderListEmptyComponent) return props.renderListEmptyComponent()
            return (
                <View style={styles.container}>
                    <TouchableOpacity onPress={() => reload && reload()}>
                        <Text style={styles.text}>{RefreshText.EmptyData}</Text>
                    </TouchableOpacity>
                </View>
            )
        default:
            return <View />
    }
})


const ListHeaderComponent = React.memo((props: RefreshListProps) => {
    const { refreshState } = props
    switch (refreshState) {
        case RefreshState.HeaderRefreshing:
            return (
                <View style={{ ...styles.container, }}>
                    <Text style={{ ...styles.text, }}>{RefreshText.HeaderRefreshing}</Text>
                </View>
            )
        default:
            return <View />
    }
})




const styles = StyleSheet.create({
    container: {
        display: 'flex',
        flexDirection: 'column',
        justifyContent: "center",
        alignItems: 'center',
        height: 44,
        // backgroundColor:'cyan'
    },
    text: {
        color: 'gray',
        lineHeight: 16,
        fontSize: 13,
    },
})

